package com.ifnk.portaljava.dapWeb.socket;
/**
 * <p>Title: 客户端连接类</p>
 *
 * <p>Description: </p>
 *
 * <p>Copyright: Copyright (c) 2010</p>
 *
 * <p>Company: </p>
 *
 * @author WenSheng.Song.hlyt@gmail.com
 * @version 1.0
 * <p>
 * Client:
 * 管理与WEBPROXY之间的连接：创建、断开、发送心跳包
 * 负责从WEBPROXY接收数据流，并寻找包边界，恢复出数据包
 * 负责周期性检查http session的状态，如有异常则做相应处理
 * 调用其它对象完成业务逻辑的处理
 * 提供Start/Stop/Query等方法合flex能间接控制本对象
 */

/**
 * Client:
 *管理与WEBPROXY之间的连接：创建、断开、发送心跳包
 *负责从WEBPROXY接收数据流，并寻找包边界，恢复出数据包
 *负责周期性检查http session的状态，如有异常则做相应处理
 *调用其它对象完成业务逻辑的处理
 *提供Start/Stop/Query等方法合flex能间接控制本对象
 *
 */

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.servlet.http.HttpSession;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.Timer;

public class Client extends Thread {

    private static Log loger = LogFactory.getLog(Client.class);
    private Timer timer = new Timer(true);

    private SocketProperty sp;
    private ClientProperty cp;
    private String clientId;
    private HttpSession session;

    private boolean removable;

    public String getProxySessionId() {
        return proxySessionId;
    }

    public void setProxySessionId(String proxySessionId) {
        this.proxySessionId = proxySessionId;
    }

    private String proxySessionId;


    public Timer getTimer() {
        return timer;
    }

    public void setTimer(Timer timer) {
        this.timer = timer;
    }

    public SocketProperty getSp() {
        return sp;
    }

    public void setSp(SocketProperty sp) {
        this.sp = sp;
    }

    public ClientProperty getCp() {
        return cp;
    }

    public void setCp(ClientProperty cp) {
        this.cp = cp;
    }

    public String getClientId() {
        return clientId;
    }

    public void setClientId(String clientId) {
        this.clientId = clientId;
    }

    public HttpSession getSession() {
        return session;
    }

    public void setSession(HttpSession session) {
        this.session = session;
    }

    public Client(String clientId) {
        Locale locale = Locale.ENGLISH;
        ResourceBundle localResource = ResourceBundle.getBundle("Socket",
                locale);
        String address = localResource.getString("socket.address");
        int port = Integer.parseInt(localResource.getString("socket.port"));
        sp = new SocketProperty();
        sp.createSocket(address, port);
        cp = new ClientProperty();
        cp.setClientId(clientId);
        cp.setRequestDateFromProxyId(clientId);
        cp.setTimeout(false);
        this.clientId = clientId;
    }

    public Client(String clientId, HttpSession session) {
        //取本地Socket连接可以在程序一启动的时候就开始
        Locale locale = Locale.ENGLISH;
        ResourceBundle localResource = ResourceBundle.getBundle("Socket",
                locale);
        String address = localResource.getString("socket.address");
        int port = Integer.parseInt(localResource.getString("socket.port"));
        sp = new SocketProperty();
        sp.createSocket(address, port);
        cp = new ClientProperty();
        cp.setClientId(clientId);
        cp.setRequestDateFromProxyId(clientId);
        cp.setTimeout(false);
        this.clientId = clientId;
        this.session = session;

    }

    public Client(String clientId, HttpSession session, String address, int port) {
        Locale locale = Locale.ENGLISH;
        ResourceBundle localResource = ResourceBundle.getBundle("Socket",
                locale);
        sp = new SocketProperty();
        sp.createSocket(address, port);
        cp = new ClientProperty();
        cp.setClientId(clientId);
        cp.setRequestDateFromProxyId(clientId);
        cp.setTimeout(false);
        this.clientId = clientId;
        this.session = session;
    }

    public void run() {
        //向proxy发送心跳
        @SuppressWarnings("unused")
        TimerTask.HeartSend hs = new TimerTask().new HeartSend(cp, sp);
        //检查proxy发送过来的心跳包，如果过期则停止socket连接
        @SuppressWarnings("unused")
        TimerTask.HeartBeat hb = new TimerTask().new HeartBeat(cp, sp);
        //检查页面session，如果session过期，则停止socket连接
        TimerTask.SessionOver so = new TimerTask().new SessionOver(clientId,
                session, sp, cp);

        // not necessary for heart beat send and timer
        //timer.schedule(hs, 0, 2000);
        //timer.schedule(hb, 0, 5000);
        timer.schedule(so, 0, 30000);

        SocketRead sr = new SocketRead(sp, cp);
        sr.recieveDataFromPROXY(this.clientId);
        loger.info("hi, quit socket read and cp.flag " + sp.getFlag());

        while (!cp.isTimeout()) {
            try {
                sleep(5000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }


        destroyClientThread();
    }

    private void destroyClientThread() {
        //loger.debug("Client.destroyClientThread()");
        try {
            if (sp != null)
                sp.destroySocket();
            destroyProcessThread();

            timer.cancel();
//			hs = null;
//			timer = null;

            // BUG!!! remove here maybe remove the new client
            //CallTraceServlet.threadMap.remove(clientId);
            // now remove a time out client at TimerTask
            // BUG!!! because timer cancel before, maybe cannot remove correctly
            // noe remove a time out client on CallTraceServlet
        } catch (Exception e) {
            sp.flag = false;
            timer.cancel();
            e.printStackTrace();
            loger.error("WebServer Exception " + e.toString());
        } finally {
            // todo  删除 文件
            //this.deleteFileFromProxy();
            cp = null;
            loger.info("WebServer Client destroyed SessionId " + this.clientId);
        }
    }

    private void destroyProcessThread() {
        if (cp != null) {
            if (cp.process.size() > 0) {
                for (int i = 0; i < cp.process.size(); i++) {
                    cp.process.get(i).interrupt();
                }
            }
            if (cp.processRawData != null) {
                cp.processRawData.interrupt();
            }

            if (cp.sendThreads.size() > 0) {
                for (int i = 0; i < cp.sendThreads.size(); i++) {
                    cp.sendThreads.get(i).interrupt();
                }
            }
        }
        cp.packets.clear();
        cp.data.clear();
    }

    public void deleteFileFromProxy() {
        if (this.proxySessionId != null) {
            loger.info("WebServer Client delete file from proxy SessionId: " + proxySessionId);
            ProcessRawDataAll.deleteSessionFilesUtil(proxySessionId);
        }

    }

    public void setRemovable(boolean removable) {
        this.removable = removable;
    }

    public boolean isRemovable() {
        return removable;
    }

}
